package bgai.players;

import bgai.ai.minimax.Board;
import bgai.ai.minimax.Search;
import bgai.gamelogic.Backgammon;
import bgai.gamelogic.CheckerColor;
import bgai.gamelogic.Move;

public abstract class ComputerPlayer extends AbstractPlayer {
	/**
	 * Profondita' massima di ricerca
	 */
	protected int maxDepth;
	
	/**
	 * Tipoe di ricerca
	 */
	SearchType type;

	protected final double bestThreshold= 1/2;
	protected final double goodThreshold= 0;
	
	public enum SearchType {EXPECTIMAX, STAR1, STAR2};
	
	public ComputerPlayer(CheckerColor color, int maxDepth) {
		super(color);
		this.maxDepth= maxDepth;
		type= SearchType.STAR2;
	}
	
	public ComputerPlayer(CheckerColor color, int maxDepth, SearchType type) {
		super(color);
		this.maxDepth= maxDepth;
		this.type= type;
	}

	/**
	 * Restituisce la profondita' di ricerca
	 * @return
	 */
	public int getMaxDepth() {
		return maxDepth;
	}
	
	@Override
	public Move bestMove(Backgammon bg) {
		switch (type) {
		case EXPECTIMAX:
			return (Move) Search.bestMoveExpectimax(this, bg, maxDepth);
			
		case STAR1:
			Search.STAR2= false;
			return (Move) Search.bestMoveStar(this, bg, maxDepth);
			
		case STAR2:
			Search.STAR2= true;
			return (Move) Search.bestMoveStar(this, bg, maxDepth);
			
		default:
			throw new RuntimeException("ARGH!!!!!!");
		}
		
	}

	@Override
	public boolean isHuman() {
		return false;
	}
	

	@Override
	public double upperBound() {
		return 1;
	}

	@Override
	public double lowerBound() {
		return -1;
	}
	
	@Override
	public boolean hasBestQuality(Board board, boolean isMaxNode) {
		double score= evaluate(board, isMaxNode);
		if (isMaxNode) {
			// massimizzo
			if (score>=bestThreshold) return true;
			else return false;
		} else {
			// minimizzo
			if (score<=-bestThreshold) return true;
			else return false;
		}
	}

	@Override
	public boolean hasGoodQuality(Board board, boolean isMaxNode) {
		double score= evaluate(board, isMaxNode);
		if (isMaxNode) {
			// massimizzo
			if (score>=goodThreshold) return true;
			else return false;
		} else {
			// minimizzo
			if (score<=-goodThreshold) return true;
			else return false;
		}
	}
}
